#pragma once

#include "devcan.hpp"

class robot_motor: public robot_can_dev
{
public:
    static const int max_motor_count = 16;

    /* motor list */
    enum Motor_ID {mmotA=1, mmotB};

    /* get id from motor list */
    #define ID(x) ((int)x)

    /* flags */
    enum Mode_t {Mode_unset, Mode_init, Mode_speed, Mode_dist}; 
    enum Boot_up_t {NBootup, Bootup};
    enum Ops_flag_t {Preope, Ope};

public: 

    static robot_motor& instance(void);

    void motor_init(Motor_ID mid);
    void motor_stop(Motor_ID mid);
    void motor_set_modespeed(Motor_ID mid);
    void motor_set_modedist(Motor_ID mid);
    void motor_set_speed(Motor_ID mid, rt_uint8_t data[], int len);
    void motor_set_dist(Motor_ID mid, rt_uint8_t data[], int len);
    void motor_disable(Motor_ID mid);
    void motor_enable(Motor_ID mid);
    void motor_reset(Motor_ID mid);
    void motor_qstop(Motor_ID mid);

private:
    static robot_motor* p;

    /* delete */
#ifdef ROBOT_CPP14
    robot_motor(const robot_motor&) = delete;
    robot_motor& operator=(const robot_motor&) = delete;
#else
    robot_motor(const robot_motor&);
    robot_motor& operator=(const robot_motor&);
#endif

    robot_motor(robot_can_bus* b);

    ~robot_motor();

    void wait_boot_up(Motor_ID mid);

    void cmode_from_unset(Motor_ID mid);

    void cmode_to_init(Motor_ID mid);

    Mode_t move_mode_flag[max_motor_count];

    Boot_up_t bp_flag[max_motor_count];

    Ops_flag_t op_flag[max_motor_count];
};